﻿#pragma once
#include <define.h>
#include <string_helper.hpp>
#include <stdexcept>
#include <regex>

// params 类用于管理和处理键值对形式的参数
class params
{
    // 使用 std::map 存储参数，键和值均为 std::string 类型
	std::map<std::string, std::string> _params;

public:
    // 默认构造函数，初始化一个空的 params 对象
	params() = default;

    // 带参数的构造函数，使用给定的参数初始化 _params
	params(const std::map<std::string, std::string>& params) : _params(params) {}

    // 设置参数数据，用给定的参数 map 覆盖 _params
	void set_data(const std::map<std::string, std::string>& params) 
	{
		_params = params;
	}

    // 获取当前存储的参数数据，返回一个包含所有参数的 std::map
	std::map<std::string, std::string> data() const
	{
		return _params;
	}
	
    // 构造函数，从一个字符串初始化 _params
    // 该字符串是以 "&" 分隔的键值对，每个键值对用 "=" 分隔
	params(const std::string& param)
	{
		_params.clear();  // 清空当前参数
		auto param_pair = string_helper::split(param, '&');  // 按 "&" 分隔字符串为多个键值对
		for (auto it : param_pair)
		{
			auto param = string_helper::split(it, '=');  // 按 "=" 分隔每个键值对
			_params[param[0]] = param[1];  // 将键值对存储到 _params 中
		}
	}

    // 模板函数，允许通过 char 数组键名获取参数值
    // 该函数会将 char 数组转换为 std::string 然后调用另一个 get 函数
	template <typename T>
	T get(const char key[]) const
	{
		return get<T>(std::string(key));
	}

private:
    // 模板函数，通过 std::string 键名获取参数值，并转换为指定的类型 T
    // 下面的每个模板特化版本处理不同的类型 T

    // 处理 const char* 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, const char*>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return it->second.c_str();  // 返回值的 C 字符串形式
	}

    // 处理 std::string 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, std::string>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return it->second;  // 返回值的 std::string 形式
	}

    // 处理 code_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, code_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return code_t(it->second.c_str());  // 将字符串值转换为 code_t 对象并返回
	}

    // 处理 int8_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, int8_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return static_cast<int8_t>(std::atoi(it->second.c_str()));  // 将字符串值转换为 int8_t 并返回
	}

    // 处理 uint8_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, uint8_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return static_cast<uint8_t>(std::atoi(it->second.c_str()));  // 将字符串值转换为 uint8_t 并返回
	}

    // 处理 int16_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, int16_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return static_cast<int16_t>(std::atoi(it->second.c_str()));  // 将字符串值转换为 int16_t 并返回
	}

    // 处理 uint16_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, uint16_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return static_cast<uint16_t>(std::atoi(it->second.c_str()));  // 将字符串值转换为 uint16_t 并返回
	}

    // 处理 int32_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, int32_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return std::atoi(it->second.c_str());  // 将字符串值转换为 int32_t 并返回
	}

    // 处理 uint32_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, uint32_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return static_cast<uint32_t>(std::atoi(it->second.c_str()));  // 将字符串值转换为 uint32_t 并返回
	}

    // 处理 double_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, double_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return std::atof(it->second.c_str());  // 将字符串值转换为 double_t 并返回
	}

    // 处理 int64_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, int64_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return std::atoll(it->second.c_str());  // 将字符串值转换为 int64_t 并返回
	}
	
    // 处理 uint64_t 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, uint64_t>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		return static_cast<uint64_t>(std::atoll(it->second.c_str()));  // 将字符串值转换为 uint64_t 并返回
	}
	
    // 处理 bool 类型的 get 函数特化
	template <typename T>
	typename std::enable_if<std::is_same<T, bool>::value, T>::type get(const std::string& key) const
	{
		auto it = _params.find(key);  // 查找 key 是否存在于 _params 中
		if (it == _params.end())  // 如果 key 不存在，抛出异常
		{
			throw std::invalid_argument("key not found : " + key);
		}
		// 判断字符串值是否为 "true" (大小写均可)，或是否可以转换为非零数值
		return "true" == it->second || "True" == it->second || "TRUE" == it->second || std::atoll(it->second.c_str()) > 0;
	}
};
